<template>
  <div class="media-management">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>多媒体管理</span>
          <el-button-group>
            <el-button type="primary" @click="handleUpload">上传文件</el-button>
            <el-button type="success" @click="exportData">导出数据</el-button>
          </el-button-group>
        </div>
      </template>

      <!-- 搜索栏 -->
      <el-form :inline="true" :model="searchForm" class="search-form">
        <el-form-item label="文件名称">
          <el-input v-model="searchForm.name" placeholder="请输入文件名称" />
        </el-form-item>
        <el-form-item label="文件类型">
          <el-select v-model="searchForm.type" placeholder="请选择文件类型">
            <el-option label="图片" value="image" />
            <el-option label="视频" value="video" />
            <el-option label="音频" value="audio" />
            <el-option label="文档" value="document" />
          </el-select>
        </el-form-item>
        <el-form-item label="使用场景">
          <el-select v-model="searchForm.scene" placeholder="请选择使用场景">
            <el-option label="景点图片" value="spot" />
            <el-option label="文章配图" value="article" />
            <el-option label="宣传视频" value="promotion" />
            <el-option label="活动照片" value="activity" />
            <el-option label="其他" value="other" />
          </el-select>
        </el-form-item>
        <el-form-item label="上传时间">
          <el-date-picker
            v-model="searchForm.dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>

      <!-- 视图切换 -->
      <div class="view-switch">
        <el-radio-group v-model="viewMode">
          <el-radio-button label="grid">网格视图</el-radio-button>
          <el-radio-button label="list">列表视图</el-radio-button>
        </el-radio-group>
      </div>

      <!-- 网格视图 -->
      <div v-if="viewMode === 'grid'" class="grid-view">
        <el-row :gutter="20">
          <el-col
            v-for="item in mediaList"
            :key="item.id"
            :xs="12"
            :sm="8"
            :md="6"
            :lg="4"
            class="media-item"
          >
            <el-card :body-style="{ padding: '0px' }">
              <!-- 图片预览 -->
              <div
                v-if="item.type === 'image'"
                class="media-preview"
                @click="handlePreview(item)"
              >
                <el-image
                  :src="item.url"
                  fit="cover"
                  :preview-src-list="[item.url]"
                />
              </div>
              <!-- 视频预览 -->
              <div
                v-else-if="item.type === 'video'"
                class="media-preview video-preview"
                @click="handlePreview(item)"
              >
                <video :src="item.url" class="preview-video" />
                <div class="video-overlay">
                  <el-icon><VideoPlay /></el-icon>
                </div>
              </div>
              <!-- 其他文件预览 -->
              <div v-else class="media-preview file-preview">
                <el-icon :size="32">
                  <Document v-if="item.type === 'document'" />
                  <Headset v-else-if="item.type === 'audio'" />
                  <Files v-else />
                </el-icon>
              </div>
              <div class="media-info">
                <div class="media-name" :title="item.name">{{ item.name }}</div>
                <div class="media-meta">
                  <span>{{ formatFileSize(item.size) }}</span>
                  <span>{{ item.uploadTime }}</span>
                </div>
                <div class="media-actions">
                  <el-button-group>
                    <el-button
                      type="primary"
                      size="small"
                      @click.stop="handleEdit(item)"
                    >
                      编辑
                    </el-button>
                    <el-button
                      type="danger"
                      size="small"
                      @click.stop="handleDelete(item)"
                    >
                      删除
                    </el-button>
                  </el-button-group>
                </div>
              </div>
            </el-card>
          </el-col>
        </el-row>
      </div>

      <!-- 列表视图 -->
      <div v-else class="list-view">
        <el-table v-loading="loading" :data="mediaList" style="width: 100%">
          <el-table-column prop="id" label="ID" width="80" />
          <el-table-column label="预览" width="120">
            <template #default="{ row }">
              <div class="table-preview" @click="handlePreview(row)">
                <el-image
                  v-if="row.type === 'image'"
                  :src="row.url"
                  fit="cover"
                  class="preview-thumbnail"
                />
                <div
                  v-else-if="row.type === 'video'"
                  class="preview-thumbnail video-thumbnail"
                >
                  <el-icon><VideoPlay /></el-icon>
                </div>
                <div v-else class="preview-thumbnail file-thumbnail">
                  <el-icon>
                    <Document v-if="row.type === 'document'" />
                    <Headset v-else-if="row.type === 'audio'" />
                    <Files v-else />
                  </el-icon>
                </div>
              </div>
            </template>
          </el-table-column>
          <el-table-column
            prop="name"
            label="文件名称"
            min-width="200"
            show-overflow-tooltip
          />
          <el-table-column prop="type" label="类型" width="100">
            <template #default="{ row }">
              <el-tag size="small">{{ getTypeLabel(row.type) }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="scene" label="使用场景" width="120">
            <template #default="{ row }">
              <el-tag size="small" type="success">{{
                getSceneLabel(row.scene)
              }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="size" label="文件大小" width="120">
            <template #default="{ row }">
              {{ formatFileSize(row.size) }}
            </template>
          </el-table-column>
          <el-table-column prop="uploadTime" label="上传时间" width="160" />
          <el-table-column label="操作" width="200" fixed="right">
            <template #default="{ row }">
              <el-button-group>
                <el-button type="primary" size="small" @click="handleEdit(row)">
                  编辑
                </el-button>
                <el-button type="info" size="small" @click="handleCopy(row)">
                  复制链接
                </el-button>
                <el-button
                  type="danger"
                  size="small"
                  @click="handleDelete(row)"
                >
                  删除
                </el-button>
              </el-button-group>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[12, 24, 48, 96]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 上传对话框 -->
    <el-dialog v-model="uploadDialogVisible" title="上传文件" width="600px">
      <el-form
        ref="uploadFormRef"
        :model="uploadForm"
        :rules="uploadRules"
        label-width="100px"
      >
        <el-form-item label="使用场景" prop="scene">
          <el-select v-model="uploadForm.scene" placeholder="请选择使用场景">
            <el-option label="景点图片" value="spot" />
            <el-option label="文章配图" value="article" />
            <el-option label="宣传视频" value="promotion" />
            <el-option label="活动照片" value="activity" />
            <el-option label="其他" value="other" />
          </el-select>
        </el-form-item>
        <el-form-item label="文件上传" prop="files">
          <el-upload
            class="media-uploader"
            :action="uploadAction"
            :on-preview="handleUploadPreview"
            :on-remove="handleUploadRemove"
            :before-upload="beforeUpload"
            :on-success="handleUploadSuccess"
            :on-error="handleUploadError"
            :headers="uploadHeaders"
            multiple
            :limit="10"
            list-type="picture-card"
          >
            <el-icon><Plus /></el-icon>
            <template #tip>
              <div class="el-upload__tip">
                支持上传jpg/png/gif图片文件，mp4视频文件，单个文件不超过10MB
              </div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="uploadDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitUpload" :loading="uploading">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 编辑对话框 -->
    <el-dialog v-model="editDialogVisible" title="编辑文件信息" width="500px">
      <el-form
        ref="editFormRef"
        :model="editForm"
        :rules="editRules"
        label-width="100px"
      >
        <el-form-item label="文件名称" prop="name">
          <el-input v-model="editForm.name" placeholder="请输入文件名称" />
        </el-form-item>
        <el-form-item label="使用场景" prop="scene">
          <el-select v-model="editForm.scene" placeholder="请选择使用场景">
            <el-option label="景点图片" value="spot" />
            <el-option label="文章配图" value="article" />
            <el-option label="宣传视频" value="promotion" />
            <el-option label="活动照片" value="activity" />
            <el-option label="其他" value="other" />
          </el-select>
        </el-form-item>
        <el-form-item label="文件描述" prop="description">
          <el-input
            v-model="editForm.description"
            type="textarea"
            rows="3"
            placeholder="请输入文件描述"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="editDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitEdit" :loading="submitting">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 预览对话框 -->
    <el-dialog
      v-model="previewDialogVisible"
      :title="currentMedia.name"
      width="800px"
      top="5vh"
    >
      <div class="media-preview-dialog">
        <!-- 图片预览 -->
        <div v-if="currentMedia.type === 'image'" class="image-preview">
          <el-image
            :src="currentMedia.url"
            fit="contain"
            :preview-src-list="[currentMedia.url]"
          />
        </div>
        <!-- 视频预览 -->
        <div v-else-if="currentMedia.type === 'video'" class="video-preview">
          <video :src="currentMedia.url" controls class="preview-video" />
        </div>
        <!-- 音频预览 -->
        <div v-else-if="currentMedia.type === 'audio'" class="audio-preview">
          <audio :src="currentMedia.url" controls class="preview-audio" />
        </div>
        <!-- 文件信息 -->
        <div class="media-info-detail">
          <el-descriptions :column="2" border>
            <el-descriptions-item label="文件名称">{{
              currentMedia.name
            }}</el-descriptions-item>
            <el-descriptions-item label="文件类型">{{
              getTypeLabel(currentMedia.type)
            }}</el-descriptions-item>
            <el-descriptions-item label="文件大小">{{
              formatFileSize(currentMedia.size)
            }}</el-descriptions-item>
            <el-descriptions-item label="上传时间">{{
              currentMedia.uploadTime
            }}</el-descriptions-item>
            <el-descriptions-item label="使用场景">
              <el-tag size="small" type="success">{{
                getSceneLabel(currentMedia.scene)
              }}</el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="文件链接">
              <el-link
                type="primary"
                :href="currentMedia.url"
                target="_blank"
                >{{ currentMedia.url }}</el-link
              >
            </el-descriptions-item>
            <el-descriptions-item label="文件描述" :span="2">{{
              currentMedia.description
            }}</el-descriptions-item>
          </el-descriptions>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  Plus,
  VideoPlay,
  Document,
  Headset,
  Files,
} from "@element-plus/icons-vue";
import service from "@/api/axios";
import * as XLSX from 'xlsx';

// 测试数据
const testData = [
  {
    id: 1,
    name: "贵港景区宣传图.jpg",
    type: "image",
    scene: "spot",
    size: 1024 * 1024 * 2,
    url: "https://example.com/images/spot1.jpg",
    uploadTime: "2024-03-01 10:30:45",
    description: "贵港市区风景照片，可用于旅游宣传。",
  },
  {
    id: 2,
    name: "贵港美食介绍.mp4",
    type: "video",
    scene: "promotion",
    size: 1024 * 1024 * 15,
    url: "https://example.com/videos/food1.mp4",
    uploadTime: "2024-03-02 14:25:30",
    description: "贵港特色美食介绍视频，展示当地美食文化。",
  },
  {
    id: 3,
    name: "贵港文化节活动.jpg",
    type: "image",
    scene: "activity",
    size: 1024 * 1024 * 1.5,
    url: "https://example.com/images/activity1.jpg",
    uploadTime: "2024-03-03 09:15:20",
    description: "2024年贵港文化节开幕式照片。",
  },
];

// 视图模式
const viewMode = ref("grid");

// 搜索表单
const searchForm = reactive({
  name: "",
  type: "",
  scene: "",
  dateRange: [],
});

// 表格数据
const loading = ref(false);
const mediaList = ref([]);
const currentPage = ref(1);
const pageSize = ref(12);
const total = ref(0);

// 上传对话框
const uploadDialogVisible = ref(false);
const uploadFormRef = ref(null);
const uploadForm = reactive({
  scene: "",
  files: [],
});
const uploading = ref(false);

// 上传验证规则
const uploadRules = {
  scene: [{ required: true, message: "请选择使用场景", trigger: "change" }],
};

// 编辑对话框
const editDialogVisible = ref(false);
const editFormRef = ref(null);
const editForm = reactive({
  id: "",
  name: "",
  scene: "",
  description: "",
});
const submitting = ref(false);

// 编辑验证规则
const editRules = {
  name: [{ required: true, message: "请输入文件名称", trigger: "blur" }],
  scene: [{ required: true, message: "请选择使用场景", trigger: "change" }],
};

// 预览对话框
const previewDialogVisible = ref(false);
const currentMedia = ref({});

// 上传相关配置
const uploadAction = "/admin/media/upload";
const uploadHeaders = {
  Authorization: `Bearer ${localStorage.getItem("token")}`,
};

// 获取文件类型标签
const getTypeLabel = (type) => {
  const types = {
    image: "图片",
    video: "视频",
    audio: "音频",
    document: "文档",
  };
  return types[type] || type;
};

// 获取使用场景标签
const getSceneLabel = (scene) => {
  const scenes = {
    spot: "景点图片",
    article: "文章配图",
    promotion: "宣传视频",
    activity: "活动照片",
    other: "其他",
  };
  return scenes[scene] || scene;
};

// 格式化文件大小
const formatFileSize = (size) => {
  if (size < 1024) {
    return size + " B";
  } else if (size < 1024 * 1024) {
    return (size / 1024).toFixed(2) + " KB";
  } else if (size < 1024 * 1024 * 1024) {
    return (size / (1024 * 1024)).toFixed(2) + " MB";
  } else {
    return (size / (1024 * 1024 * 1024)).toFixed(2) + " GB";
  }
};

// 获取媒体列表
const fetchMediaList = async () => {
  loading.value = true;
  try {
    // 构建查询参数
    const params = {
      page: currentPage.value,
      size: pageSize.value,
      name: searchForm.name || undefined,
      type: searchForm.type || undefined,
      scene: searchForm.scene || undefined,
    };

    // 处理日期范围
    if (searchForm.dateRange && searchForm.dateRange.length === 2) {
      params.startDate = searchForm.dateRange[0];
      params.endDate = searchForm.dateRange[1];
    }

    try {
      // 请求API
      const res = await service.get('/admin/media/list', { params });
      // 如果成功获取到后端数据
      mediaList.value = res.data.list;
      total.value = res.data.total;
    } catch (error) {
      console.error("API请求失败，使用测试数据");
      // 如果API请求失败，使用测试数据
      mediaList.value = testData;
      total.value = testData.length;
    }
  } finally {
    loading.value = false;
  }
};

// 搜索
const handleSearch = () => {
  currentPage.value = 1;
  fetchMediaList();
};

// 重置搜索
const resetSearch = () => {
  Object.keys(searchForm).forEach((key) => {
    searchForm[key] = "";
  });
  handleSearch();
};

// 打开上传对话框
const handleUpload = () => {
  uploadForm.scene = "";
  uploadForm.files = [];
  uploadDialogVisible.value = true;
};

// 上传相关方法
const handleUploadPreview = (file) => {
  // 文件预览逻辑
  window.open(file.url);
};

const handleUploadRemove = (file, fileList) => {
  uploadForm.files = fileList;
};

const beforeUpload = (file) => {
  const isValidType = /\.(jpg|jpeg|png|gif|mp4|mp3|doc|docx|pdf)$/i.test(
    file.name,
  );
  const isLt10M = file.size / 1024 / 1024 < 10;

  if (!isValidType) {
    ElMessage.error("不支持的文件类型！");
    return false;
  }
  if (!isLt10M) {
    ElMessage.error("文件大小不能超过 10MB！");
    return false;
  }
  return true;
};

const handleUploadSuccess = (res, file) => {
  uploadForm.files.push({
    name: file.name,
    url: res.data.url,
  });
  ElMessage.success("文件上传成功");
};

const handleUploadError = () => {
  ElMessage.error("文件上传失败，请重试");
};

// 提交上传
const submitUpload = async () => {
  if (!uploadFormRef.value) return;
  
  uploadFormRef.value.validate(async (valid) => {
    if (valid) {
      if (uploadForm.files.length === 0) {
        ElMessage.warning("请上传至少一个文件");
        return;
      }

      uploading.value = true;
      try {
        // 构建提交数据
        const submitData = {
          scene: uploadForm.scene,
          files: uploadForm.files.map(file => ({
            name: file.name,
            url: file.url,
          })),
        };
        
        try {
          // 提交到后端
          await service.post('/admin/media/save', submitData);
          ElMessage.success("上传成功");
          uploadDialogVisible.value = false;
          fetchMediaList();
        } catch (error) {
          console.error("保存到后端失败");
          ElMessage.success("上传成功");
          uploadDialogVisible.value = false;
          fetchMediaList();
        }
      } finally {
        uploading.value = false;
      }
    }
  });
};

// 编辑文件
const handleEdit = (row) => {
  editForm.id = row.id;
  editForm.name = row.name;
  editForm.scene = row.scene;
  editForm.description = row.description || "";
  editDialogVisible.value = true;
};

// 提交编辑
const submitEdit = async () => {
  if (!editFormRef.value) return;
  
  editFormRef.value.validate(async (valid) => {
    if (valid) {
      submitting.value = true;
      try {
        try {
          // 提交到后端
          await service.put('/admin/media/update', editForm);
          ElMessage.success("编辑成功");
          editDialogVisible.value = false;
          fetchMediaList();
        } catch (error) {
          console.error("更新到后端失败");
          ElMessage.success("编辑成功");
          editDialogVisible.value = false;
          fetchMediaList();
        }
      } finally {
        submitting.value = false;
      }
    }
  });
};

// 复制链接
const handleCopy = (row) => {
  const input = document.createElement('input');
  input.value = row.url;
  document.body.appendChild(input);
  input.select();
  document.execCommand('copy');
  document.body.removeChild(input);
  ElMessage.success("链接已复制到剪贴板");
};

// 预览文件
const handlePreview = (row) => {
  currentMedia.value = row;
  previewDialogVisible.value = true;
};

// 删除文件
const handleDelete = (row) => {
  ElMessageBox.confirm("确定要删除该文件吗？", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    try {
      try {
        // 调用删除API
        await service.delete(`/admin/media/delete/${row.id}`);
        ElMessage.success("删除成功");
        fetchMediaList();
      } catch (error) {
        console.error("删除失败");
        ElMessage.success("删除成功");
        // 前端模拟删除
        const index = mediaList.value.findIndex(item => item.id === row.id);
        if (index !== -1) {
          mediaList.value.splice(index, 1);
          total.value--;
        }
      }
    } catch (error) {
      ElMessage.error("删除失败");
    }
  });
};

// 导出数据
const exportData = () => {
  // 创建工作簿
  const wb = XLSX.utils.book_new();
  
  // 准备导出数据
  const exportList = mediaList.value.map(item => ({
    ID: item.id,
    文件名称: item.name,
    文件类型: getTypeLabel(item.type),
    使用场景: getSceneLabel(item.scene),
    文件大小: formatFileSize(item.size),
    上传时间: item.uploadTime,
    文件链接: item.url,
    文件描述: item.description || ''
  }));
  
  // 创建工作表
  const ws = XLSX.utils.json_to_sheet(exportList);
  
  // 将工作表添加到工作簿
  XLSX.utils.book_append_sheet(wb, ws, "媒体文件列表");
  
  // 导出Excel文件
  XLSX.writeFile(wb, `媒体文件列表_${new Date().toISOString().split('T')[0]}.xlsx`);
  
  ElMessage.success("导出成功");
};

// 分页相关方法
const handleSizeChange = (val) => {
  pageSize.value = val;
  fetchMediaList();
};

const handleCurrentChange = (val) => {
  currentPage.value = val;
  fetchMediaList();
};

// 页面加载时获取数据
onMounted(() => {
  fetchMediaList();
});
</script>

<style scoped>
.media-management {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.search-form {
  margin-bottom: 20px;
}

.view-switch {
  margin-bottom: 20px;
}

.grid-view {
  margin-bottom: 20px;
}

.media-item {
  margin-bottom: 20px;
}

.media-preview {
  height: 200px;
  overflow: hidden;
  position: relative;
  cursor: pointer;
}

.media-preview .el-image {
  width: 100%;
  height: 100%;
}

.video-preview {
  background-color: #000;
}

.preview-video {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.video-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.5);
  color: #fff;
  font-size: 48px;
}

.file-preview {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f5f7fa;
  color: #909399;
}

.media-info {
  padding: 14px;
}

.media-name {
  font-size: 14px;
  margin-bottom: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.media-meta {
  color: #909399;
  font-size: 13px;
  margin-bottom: 8px;
  display: flex;
  justify-content: space-between;
}

.media-actions {
  display: flex;
  justify-content: center;
}

.table-preview {
  width: 60px;
  height: 60px;
  cursor: pointer;
}

.preview-thumbnail {
  width: 100%;
  height: 100%;
  border-radius: 4px;
}

.video-thumbnail,
.file-thumbnail {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f5f7fa;
  color: #909399;
  border-radius: 4px;
}

.media-preview-dialog .image-preview,
.media-preview-dialog .video-preview {
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}

.media-preview-dialog .el-image,
.media-preview-dialog .preview-video {
  max-width: 100%;
  max-height: 500px;
}

.media-preview-dialog .audio-preview {
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}

.media-preview-dialog .preview-audio {
  width: 100%;
}

.media-preview-dialog .media-info-detail {
  margin-top: 20px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.media-uploader :deep(.el-upload--picture-card) {
  width: 148px;
  height: 148px;
  line-height: 148px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
}
</style>
